/*
*
* 一个用于剖切的库Slice.js
*
* */

define(function(){
    
    var Slice = function (world,handle) {
        this.globalPlanesCounts = 0;
        this.sliding = 20;               //控制剪切面的拖动值
        this.boxColor = 0x6f7275;       //剖面体初始色
        this.boxFrameColor = 0x151515;       //剖面体边框色
        this.boxStateColor = 0x378a0e;       //剖面体状态色
        this.opacity = 0.2;                 //剖面体透明度
    
        this.world = world||{};
        this.event = handle.select||{};
        this.handle = handle;
        this.assistFace = [];           //剖面
        this.indexVector = [];          //顶点索引器
        this.globalPlanesContainer = {};    //剖面总和
        this.indexFace = {};    //剖面索引器
        this.PlanesContainer = null;        //单个剖面
        this.aixsFace = null;               //剖面所处的物理界面
        this.PlaneGroup = {};               //剖面体
        this.clippingCube= {
            width:2500,
            height:1000,
            depth:1500,
            position:new THREE.Vector3(0,100,0)
        };              //剖面参数
        this.dom = world.dom.renDom;
        
        this.globalPlanes = [];
        this.clipingConset = [];            //剪切面距离值
        this.globalVertices = [];           //原始顶点容器
        this.clipping = [];           //剖面存储器
        this.Empty = Object.freeze( [] );
        this.scene = world.scene;
        scope = this;
        // this.clippingAssist();           //自动初始化
    };
    
    Object.assign(Slice.prototype,{
        start:function(){
            //初始化剖面体
            //this.clippingAssist(this.clippingCube);
            this.clippingAssist();
        },
        clippingView:function(toggle){
                if(toggle!==undefined){
                    //剖面设置
                    //scope.world.renderer.localClippingEnabled = toggle;
                    scope.world.renderer.clippingPlanes = toggle ? scope.globalPlanes : scope.Empty;
                    var objcet = scope.scene.getObjectByName("clippingGroup");
                    if(objcet == undefined){
                        scope.scene.add(scope.PlaneGroup);
                        objcet = scope.PlaneGroup;
                    }
                    if(toggle){
                        scope.assistFace.forEach(function(e){
                            if(e!==undefined)e.visible = true;
                        });
                        objcet.visible = true;
                        scope.enabled();
                    }
                    else{
                        scope.assistFace.forEach(function(e){
                            if(e!==undefined)e.visible = true;
                        });
                        objcet.visible = false;
                        scope.handle.reset();
                        scope.reset();
                        scope.dispose();
                    }
                    
                }
                else{
                    scope.assistFace.forEach(function(e){
                        if(e!==undefined)e.visible = true;
                    });
                    scope.handle.reset();
                    scope.reset();
                    scope.dispose();
                    var objcet = scope.scene.getObjectByName("clippingGroup");
                    scope.scene.remove(objcet);
                }
                scope.world.update();
            },
        create: function (normal,conset,face) {
            var normals,consets;
            normals = normal || new THREE.Vector3(1,0,0);
            consets = conset || 100;
            var name = "clipping" + face;
            var clipings = new THREE.Plane(normals,consets);
            this.globalPlanesContainer[""+name+""] = clipings;
            this.indexFace[""+face+""] = clipings;
            this.globalPlanes.push(clipings);
            this.clipingConset.push(consets);
            return clipings;
        },
        
        opeation: {
        
            remove:function(name){
            
            },
        
            add:function(type){
                if(type == undefined)return;
            
            
            },
        
            //清楚所有剪切面
            clear:function(){
                this.globalPlanesContainer = {};
                //this.PlanesContainer = {};
                this.globalPlanes.length=0;
                this.globalPlanesId.length = 0;
            },
        
            //剪切面控制器
            guide:function (name,value) {
            
                if(name == undefined && value == undefined)return;
                var clipings = this.globalPlanesContainer[name];
                if(!clipings)return;
                clipings.constant = value;
            }
        
        },
        
        plan : function (vector3) {
            if(vector3==undefined)return;
            var face = this.create(new THREE.Vector3(0, -1, 0),vector3.y);
            scope.clipping.push(face);
            return face;
        },
        
        clippingAssist : function (width,height,depth,position){
        
            var width = width || 12000;
            var height = height || 4200;
            var depth = depth ||  20000;
            var position = position || new THREE.Vector3();
        
            var clippingBox = new THREE.BoxGeometry(width, height, depth);
            var boxMaterials = new THREE.MeshBasicMaterial({
                color: this.boxColor,
                opacity: this.opacity,
                transparent:true,
                side:2,
                depthTest:false,
                flatShading: true,
                vertexColors: THREE.VertexColors
            });
            var clippingB = new THREE.Mesh(clippingBox, boxMaterials);
            var helper = new THREE.BoxHelper(clippingB,this.boxFrameColor);
            var clippingG = new THREE.Group();
        
            clippingB.nmae = "clipping";
            clippingG.add(clippingB);
            clippingG.add(helper);
            clippingG.position.copy(position);
            clippingG.name = "clippingGroup";
            clippingG.visible = false;
        
            this.scene.add(clippingG);
            this.PlaneGroup = clippingG;
            clippingBox.vertices.forEach(function(e){
                scope.globalVertices.push(e.clone());
            });
            this.separateFace(clippingB);                       //生成剖面
        
        },
    
        clippingChange : function (pram,colors,boolean){
            var meshData = pram.object;
            var facesIndex = pram.faceIndex;
            var facesArray = meshData.geometry.faces;
            var color = colors ;
            switch(facesIndex){
                case 0:
                case 1:
                    changeColor(facesArray,0,1,color);
                    this.aixsFace = "F";
                    break;
                case 2:
                case 3:
                    changeColor(facesArray,2,3,color);
                    this.aixsFace = "B";
                    break;
                case 4:
                case 5:
                    changeColor(facesArray,4,5,color);
                    this.aixsFace = "T";
                    break;
                case 6:
                case 7:
                    changeColor(facesArray,6,7,color);
                    this.aixsFace = "D";
                    break;
                case 8:
                case 9:
                    changeColor(facesArray,8,9,color);
                    this.aixsFace = "R";
                    break;
                case 10:
                case 11:
                    changeColor(facesArray,10,11,color);
                    this.aixsFace = "L";
                    break;
            }
            meshData.geometry.colorsNeedUpdate = true;
        },
        
        separateFace : function (object){
            if(!object.isObject3D)return;
            var targetObject = object.geometry.faces;
            var project = [object.geometry.vertices[0]];
            var i = targetObject.length-1;
            var normal,conset;
            var aixsFace;
            for(;i>-1;i--){
                switch (i/2){
                
                    //背面剪切
                    case 0:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].x;
                        aixsFace = "B";
                        break;
                
                    //正面剪切
                    case 1:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].x;
                        aixsFace = "F";
                        break;
                
                    //顶面剪切
                    case 2:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].y;
                        aixsFace = "D";
                        break;
                
                    //底面剪切
                    case 3:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].y;
                        aixsFace = "T";
                        break;
                
                    //左侧面剪切
                    case 4:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].z;
                        aixsFace = "L";
                        break;
                
                
                    //右侧面剪切
                    case 5:
                        normal = targetObject[i].normal;
                        conset = 0.1 + project[0].z;
                        aixsFace = "R";
                        break;
                    default:
                        continue;
                }
                scope.create(normal,conset,aixsFace);
            }
            return;
        },
        enabled : function(){
            scope.handle.events.addEvent(scope.dom,"mousedown",scope.mousedown,false);
            scope.handle.events.addEvent(scope.dom,"mouseup",scope.mouseup,false);
            
        },
        dispose : function(){
            scope.handle.events.removeEvent(scope.dom,"mousedown",scope.mousedown,false);
            scope.handle.events.removeEvent(scope.dom,"mouseup",scope.mouseup,false);
            
        },
        mousedown : function (event){
            event.preventDefault();
            if(event.button !== 0)return;
            scope.event(scope.PlaneGroup.children)(event,downEvent);
            if(scope.PlanesContainer !== null){
                scope.handle.dispose();
                scope.handle.events.addEvent(scope.dom,"mousemove",scope.mousemove,false);
            }
        },
        mousemove : function (event){
            event.preventDefault();
            if(scope.PlanesContainer !== null){
                moveEvent(event,scope.PlanesContainer.object.geometry);
            }else{
                scope.handle.events.removeEvent(scope.dom,"mousemove",scope.mousemove,false);
            }
        },
        mouseup : function (event){
            event.preventDefault();
            if(scope.PlanesContainer !== null){
                scope.clippingChange(scope.PlanesContainer,this.boxStateColor);
                scope.PlanesContainer = null;
                scope.handle.events.removeEvent(scope.dom,"mousemove",scope.mousemove,false);
                scope.handle.enable();
                //scope.handle.reset();
            }
        },
        reset : function () {
            var box = scope.PlaneGroup.children;
            var object = box[0].geometry;
                object.vertices = scope.globalVertices;
                object.verticesNeedUpdate = true;
                box[0].material.needsUpdate = true;
            var face = scope.globalPlanes;
            var consets = scope.clipingConset;
            var i = face.length-1;
            for(;i>-1;i--)face[i].constant = consets[i];
            box[1].setFromObject(box[0]);
            scope.world.update();
        },
    
        
    });
    
    var scope;
    
    //执行down
    function downEvent(project){
        
        if(project.length>0){
            
            var target = project[0];
            scope.clippingChange(target,0x3fbf62,true);
            scope.PlanesContainer = target;
            
        }else{
            scope.PlanesContainer = null;
        };
        
    }
    
    //执行move
    function moveEvent(event,project) {
        
        if(project == undefined)return;
        var x = event.movementX;
        var y = event.movementY;
        var flag = scope.aixsFace;
        var box = scope.PlaneGroup.children;
        var object = project;
        var value = null;
        switch (flag){
            //X变化
            case "L":
            case "R":
                x == 0 ? value = 0 : value = (x/Math.abs(x))*scope.sliding*10;
                vectorUpdate(value,object,flag);
                break;
            
            //Y变化
            case "T":
            case "D":
                y == 0 ? value = 0 : value = (y/Math.abs(y))*scope.sliding*10;
                vectorUpdate(value,object,flag);
                break;
            
            case "B":
            case "F":
                y == 0 ? value = 0 : value = (y/Math.abs(y))*scope.sliding*10;
                vectorUpdate(value,object,flag);
                break;
            
        }
        box[1].setFromObject(box[0]);
        
    }
    
    // //更新材质
    // function needsUpdate ( material, geometry ) {
    //
    //     return function () {
    //
    //         material.side = +material.side; //Ensure number
    //         //material.color = new THREE.Color(0xff0000); //Ensure number
    //         material.needsUpdate = true;
    //         geometry.verticesNeedUpdate = true;
    //         geometry.normalsNeedUpdate = true;
    //         geometry.colorsNeedUpdate = true;
    //
    //     };
    //
    // }
    
    //变换顶点位置
    
    function vectorUpdate(value,object,flag){
        if(scope.indexVector.length == 0) return;
        var target = scope.indexVector;
        var i = target.length-1;
        var delta = value;
        var clipingFace = scope.indexFace;
        var vertices = object.vertices.slice(0);
        for(;i>-1;i--){
            var vector = vertices[target[i]];
            switch (flag){
                
                //X变化
                case "L":
                    vector.z += delta;
                    clipingFace[""+flag+""].constant = 0.1-vector.z;
                    break;
                
                case "R":
                    vector.z += delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.z;
                    break;
                
                //Y变化
                case "T":
                    vector.y += -delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.y;
                    break;
                
                case "D":
                    vector.y += -delta;
                    clipingFace[""+flag+""].constant = -0.1-vector.y;
                    break;
                
                case "B":
                    vector.x += -delta;
                    clipingFace[""+flag+""].constant = 0.1-vector.x;
                    break;
                
                case "F":
                    vector.x += delta;
                    clipingFace[""+flag+""].constant = 0.1+vector.x;
                    break;
                
            }
        }
        object.vertices = vertices;
        object.verticesNeedUpdate = true;
    }
    
    //目标面识别
    function faceId(){
    
    
    }
    
    //改变顶点颜色
    function changeColor(faceobj,indexa,indexb,color){
        var i = 0;
        var objectA = faceobj[indexa];
        var objectB = faceobj[indexb];
        var n = ( objectA instanceof THREE.Face3 ) ? 3 : 4;
        for(;i<n;i++){
            objectA.color.copy(new THREE.Color(color));
            objectB.color.copy(new THREE.Color(color));
        }
        scope.indexVector = [];
        scope.indexVector.push(objectA.a,objectA.b,objectA.c,objectB.b);
        
        // faceobj[indexa].forEach(function (value) {  });vertexColors[0] = color;
        // faceobj[indexa].vertexColors[2] = color;
        // faceobj[indexa].color.add(color);
        // faceobj[indexb].color.add(color);
        // faceobj[indexb].vertexColors[1] = color;
        // faceobj[indexb].vertexColors[2] = color;
        // faceobj[indexb].vertexColors[0] = color;
        
    }
    
    //提取指定顶点和面的数据
    function extractVertices(event,geometry) {
        var vessel = [];
        var objectA = faceobj[indexa];
        var objectB = faceobj[indexb];
        vessel.push(objectA.a,objectA.b,objectA.c,objectB.b);
        
        
        
    }
    
    
    return Slice
    
});

